/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package com.yuecai.modules.yc_gift_good.service.impl;

import com.yuecai.modules.yc_gift_good.domain.YcGift;
import com.yuecai.modules.yc_gift_good.domain.YcGiftGood;
import com.yuecai.modules.yc_gift_good.repository.YcGiftGoodRepository;
import com.yuecai.modules.yc_gift_good.repository.YcGiftRepository;
import com.yuecai.modules.yc_gift_good.service.YcGiftService;
import com.yuecai.modules.yc_gift_good.service.dto.YcGiftDto;
import com.yuecai.modules.yc_gift_good.service.dto.YcGiftQueryCriteria;
import com.yuecai.modules.yc_gift_good.service.mapstruct.YcGiftMapper;
import com.yuecai.modules.yc_gift_good.service.vo.YcGiftGoodVo;
import com.yuecai.modules.yc_gift_good.service.vo.YcGiftVo;
import com.yuecai.modules.yc_goods.domain.YcGoods;
import com.yuecai.modules.yc_goods_sku.domain.YcGoodsSku;
import com.yuecai.modules.yc_goods_sku.repository.YcGoodsSkuRepository;
import com.yuecai.utils.FileUtil;
import com.yuecai.utils.QueryHelp;
import com.yuecai.utils.ValidationUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
* @website https://el-admin.vip
* @description 服务实现
* @author dm
* @date 2020-10-26
**/
@Service
@RequiredArgsConstructor
public class YcGiftServiceImpl implements YcGiftService {

    private final YcGiftRepository ycGiftRepository;
    private final YcGiftGoodRepository ycGiftGoodRepository;
    private final YcGiftMapper ycGiftMapper;
    private final YcGoodsSkuRepository ycGoodsSkuRepository;

    @Override
    public Map<String,Object> queryAll(YcGiftQueryCriteria criteria, Pageable pageable){
        Page<YcGift> page = ycGiftRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        List<YcGift> content = page.getContent();
        Map<String, Object> map = new HashMap<>();
        ArrayList<YcGiftVo> ycGiftVos = new ArrayList<>();
        for (YcGift ycGift : content) {
            YcGiftVo ycGiftVo = new YcGiftVo();
            BeanUtils.copyProperties(ycGift,ycGiftVo);
            List<YcGiftGood> ycGiftGoodList = ycGift.getYcGiftGoodList();
            if (CollectionUtils.isNotEmpty(ycGiftGoodList)){
                ArrayList<YcGiftGoodVo> ycGiftGoodVos = new ArrayList<>();
                ycGiftGoodList.forEach(item->{
                    YcGiftGoodVo vo = new YcGiftGoodVo();
                    BeanUtils.copyProperties(item,vo);
                    Long skuId = item.getSkuId();
                    Optional<YcGoodsSku> byId = ycGoodsSkuRepository.findById(skuId);
                    if (byId.isPresent()){
                        YcGoodsSku ycGoodsSku = byId.get();
                        YcGoods ycGoods = ycGoodsSku.getYcGoods();
                        if (ycGoods!=null){
                            String name = ycGoods.getName();
                            String img = ycGoods.getImg();
                            vo.setImg(img);
                            vo.setName(name);
                        }
                    }
                    ycGiftGoodVos.add(vo);
                });
                ycGiftVo.setYcGiftGoodList(ycGiftGoodVos);
            }
            ycGiftVos.add(ycGiftVo);
        }
        map.put("content",ycGiftVos);
        map.put("totalElements",page.getTotalElements());
        return map;
    }

    @Override
    public List<YcGiftDto> queryAll(YcGiftQueryCriteria criteria){
        return ycGiftMapper.toDto(ycGiftRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public YcGiftDto findById(Integer id) {
        YcGift ycGift = ycGiftRepository.findById(id).orElseGet(YcGift::new);
        ValidationUtil.isNull(ycGift.getId(),"YcGift","id",id);
        return ycGiftMapper.toDto(ycGift);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public YcGiftDto create(YcGift resources) throws Exception {
        if (resources.getUpperLimit().equals(resources.getLowerLimit())){
            throw new Exception("下限和上限不能相等！");
        }
        YcGift giftLower = ycGiftRepository.findByLowerLimitLessThanEqualAndUpperLimitGreaterThan(resources.getLowerLimit(), resources.getLowerLimit());
        if (giftLower!=null){
            throw new Exception("下限不能处在"+giftLower.getLowerLimit()+"和"+giftLower.getUpperLimit()+"之间！");
        }
        YcGift giftUpper = ycGiftRepository.findByLowerLimitLessThanEqualAndUpperLimitGreaterThan(resources.getUpperLimit(), resources.getUpperLimit());
        if (giftUpper!=null){
            throw new Exception("上线不能处在"+giftUpper.getLowerLimit()+"和"+giftUpper.getUpperLimit()+"之间！");
        }
        List<YcGiftGood> ycGiftGoodList = resources.getYcGiftGoodList();
        resources.setYcGiftGoodList(null);
        YcGift save = ycGiftRepository.save(resources);
        save.setYcGiftGoodList(null);
        ycGiftGoodList.forEach(item->{
            item.setGiftId(save.getId());
        });
        List<YcGiftGood> ycGiftGoods = ycGiftGoodRepository.saveAll(ycGiftGoodList);
        save.setYcGiftGoodList(ycGiftGoods);
        return ycGiftMapper.toDto(save);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(YcGift resources) throws Exception {
        YcGift ycGift = ycGiftRepository.findById(resources.getId()).orElseGet(YcGift::new);
        if (resources.getUpperLimit().equals(resources.getLowerLimit())){
            throw new Exception("下限和上限不能相等！");
        }
        YcGift giftLower = ycGiftRepository.findByLowerLimitLessThanEqualAndUpperLimitGreaterThan(resources.getLowerLimit(), resources.getLowerLimit());
        boolean equals = resources.getId().equals(ycGift.getId());
        if (giftLower!=null){
            if (!equals) {
                throw new Exception("下限不能处在"+giftLower.getLowerLimit()+"和"+giftLower.getUpperLimit()+"之间！");
            }
        }
        YcGift giftUpper = ycGiftRepository.findByLowerLimitLessThanEqualAndUpperLimitGreaterThan(resources.getUpperLimit(), resources.getUpperLimit());
        if (giftUpper!=null){
            if (!equals){
                throw new Exception("上线不能处在"+giftUpper.getLowerLimit()+"和"+giftUpper.getUpperLimit()+"之间！");
            }
        }
        List<YcGiftGood> ycGiftGoodList = resources.getYcGiftGoodList();
        resources.setYcGiftGoodList(null);
        YcGift save = ycGiftRepository.save(resources);
        ycGiftGoodList.forEach(item->{
            item.setGiftId(save.getId());
        });
        ycGiftGoodRepository.saveAll(ycGiftGoodList);
    }

    @Override
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            ycGiftRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<YcGiftDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (YcGiftDto ycGift : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("订单价格下限", ycGift.getLowerLimit());
            map.put("订单价格上限", ycGift.getUpperLimit());
            map.put("时间", ycGift.getCreateTime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}